#include <gtest/gtest.h>

#include <Manager/FileManager.h>
#include <QUuid>
#include <SignatureGenerator.h>
#include <AliOSSAdapter.h>
#include <QCoreApplication>
#include <thread>
#include "Database.h"

using namespace TCServer;
using namespace TCServer::Manager;
using namespace AliOSS;

TEST(Manager_FileManager, remove)
{
    Database();
	// upload a file first	// path
	QString testPath = "testUpload/Manager/" + QUuid::createUuid().toString();

	// make sure it is not exist currently
	{
		QNetworkAccessManager m;
		QNetworkRequest req(QString("http://tcres.oss-cn-shenzhen.aliyuncs.com/%1").arg(testPath));
		auto rep = m.get(req);
		while (!rep->isFinished())
			QCoreApplication::processEvents();
		rep->deleteLater();
		ASSERT_EQ(404, rep->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt());
	}

	// upload first
	{
		// initialize
		AliOSS::SignatureGenerator gen = AliOSS::SignatureGenerator(
			"tcres",
			"sSot2oqZBG1xTcJs",
			"iwVz8BO5ewe1X1JC1CbMZTQNtdqQB6");
		AliOSSAdapter adapter("tcres", "sSot2oqZBG1xTcJs");

		// data to upload
		QByteArray data = "1234567";

		// prepare
		AliOSSUploadRequest *uploader = adapter.prepareUpload(data);
		// datetime string
		qDebug() << "dtstr org   : " << AliOSSAdapter::formatDatetime(QDateTime::currentDateTimeUtc());
		auto datetime = QDateTime::currentDateTime();
		datetime.setTime(QTime::currentTime().addSecs(-60 * 14));
		auto dtstr = AliOSSAdapter::formatDatetime(datetime.toUTC());
		qDebug() << "dtstr fixed : " << dtstr;
		// content Type
		QString contentType = "text/html";

		//ossheaders
		QMap<QString, QByteArray> ossHeaders = QMap<QString, QByteArray>({
			{ "x-oss-meta-uploadtime", QDateTime::currentDateTime().toString().toUtf8() },
			{ "x-oss-meta-uploader", "testUploader" },
		});

		// signature
		auto signature = gen.once("PUT", dtstr, testPath, uploader->fileMd5inBase64(), ossHeaders, contentType);

		// set properties
		uploader->setNeededInformation(dtstr, testPath, signature, "text/html", ossHeaders);

		// upload
		{
			bool isUploadOk = false;
			bool isUploadFailed = false;
			QObject::connect(uploader, &AliOSSUploadRequest::uploadFinished, [&]()
			{
				isUploadOk = true;
			});
			QObject::connect(uploader, &AliOSSUploadRequest::uploadFailed, [&]()
			{
				isUploadFailed = true;
			});

			// auto-delete
			QObject::connect(uploader, &AliOSSUploadRequest::uploadFinished,
				uploader, &AliOSSUploadRequest::deleteLater);
			QObject::connect(uploader, &AliOSSUploadRequest::uploadFailed,
				uploader, &AliOSSUploadRequest::deleteLater);
			QObject::connect(uploader, &AliOSSUploadRequest::uploadError,
				uploader, &AliOSSUploadRequest::deleteLater);
			uploader->upload();

			while (!isUploadOk && !isUploadFailed)
				QCoreApplication::processEvents();

			ASSERT_TRUE(isUploadOk);
		}
	}


	// make sure it is uploaded
	{
		QNetworkAccessManager m;
		QNetworkRequest req(QString("http://tcres.oss-cn-shenzhen.aliyuncs.com/%1").arg(testPath));
		auto rep = m.get(req);
		while (!rep->isFinished())
			QCoreApplication::processEvents();
		rep->deleteLater();
		ASSERT_EQ(200, rep->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt());
	}

	// then, remove it using FileManager
	{
		FileManager::instance()->removeAsync(QString("http://tcres.oss-cn-shenzhen.aliyuncs.com/%1").arg(testPath));

		// since we don't know when remove action will end, we just wait for a while.
		auto start = QTime::currentTime();
		while(start.secsTo(QTime::currentTime()) < 4)
			QCoreApplication::processEvents();
	}

	// make sure it is not exist currently
	{
		QNetworkAccessManager m;
		QNetworkRequest req(QString("http://tcres.oss-cn-shenzhen.aliyuncs.com/%1").arg(testPath));
		auto rep = m.get(req);
		while (!rep->isFinished())
			QCoreApplication::processEvents();
		rep->deleteLater();
		ASSERT_EQ(404, rep->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt());
	}

}